﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

using D6_Value_Assistance_Manager.ContextRegistryService;
using D6_Value_Assistance_Manager.SchemaService;
using D6_Value_Assistance_Manager.SearchService;
using D6_Value_Assistance_Manager.ObjectService;
using D6_Value_Assistance_Manager.QueryService;

namespace D6_Value_Assistance_Manager
{
    public class DfsWrapper
    {
#region Attributes

        protected Repository[] m_repositoryList= null;
        protected ServiceContextHeader m_scx = null;
        protected SearchServicePortClient m_searchService = null;
        protected SchemaServicePortClient m_schemaService = null;
        protected ObjectServicePortClient m_objectService = null;
        protected QueryServicePortClient m_queryService = null;

        protected Repository m_currRepository = null;
        protected String m_currRepositoryName = null;

#endregion Attributes

#region Properties
        public String[] Repositories
        {
            get
            {
                List<String> repositoryNames = new List<String>();

                foreach (Repository repositoryItem in GetRepositoryList())
                {
                    repositoryNames.Add(repositoryItem.name);
                }

                return repositoryNames.ToArray();
            }
        }


#endregion Properties


        #region Methods

        public DfsWrapper()
        {
            m_searchService = new SearchServicePortClient("SearchServicePort");
            m_schemaService = new SchemaServicePortClient("SchemaServicePort");
            m_objectService = new ObjectServicePortClient("ObjectServicePort");
            m_queryService = new QueryServicePortClient("QueryServicePort");

            m_scx = new ServiceContextHeader();
            RepositoryIdentity repositoryId = new RepositoryIdentity();
            repositoryId.repositoryName = "DMS";
            repositoryId.userName = "";
            repositoryId.password = "";

            m_scx.AddRepositoryIdentity(repositoryId);
        }

        protected Repository[] GetRepositoryList()
        {
            if (null == m_repositoryList || m_repositoryList.Count() == 0)
            {
                try
                {

                    using (OperationContextScope scope = new OperationContextScope(new OperationContext(m_searchService.InnerChannel)))
                    {
                        OperationContext.Current.OutgoingMessageHeaders.Add(m_scx);
                        m_repositoryList = m_searchService.getRepositoryList(null);
                    }


                }
                catch (Exception ex)
                {
                    ErrorWnd errorWindow = new ErrorWnd(ex);
                    errorWindow.Show();
                }

            }

            return m_repositoryList;
        }

        protected void getDctmObject(String customType)
        {
            D6_Value_Assistance_Manager.ObjectService.DataPackage dataPackage = null;

            try
            {
                //find the custom type to return
                D6_Value_Assistance_Manager.ObjectService.Qualification q = new D6_Value_Assistance_Manager.ObjectService.Qualification();
                q.String = "dm_type WHERE name = '" + customType + "'";
                q.qualificationValueType = D6_Value_Assistance_Manager.ObjectService.QualificationValueType.STRING;
                q.qualificationValueTypeSpecified = true;

                //Set the identity
                D6_Value_Assistance_Manager.ObjectService.ObjectIdentity objId = new D6_Value_Assistance_Manager.ObjectService.ObjectIdentity();
                objId.valueType = D6_Value_Assistance_Manager.ObjectService.ObjectIdentityType.QUALIFICATION;
                objId.valueTypeSpecified = true;
                objId.Item = q;
                objId.repositoryName = m_currRepositoryName;

                D6_Value_Assistance_Manager.ObjectService.ObjectIdentitySet objectIdSet = new D6_Value_Assistance_Manager.ObjectService.ObjectIdentitySet();
                objectIdSet.Identities = new D6_Value_Assistance_Manager.ObjectService.ObjectIdentity[1];
                objectIdSet.Identities[0] = objId;

                D6_Value_Assistance_Manager.ObjectService.PropertyProfile propertyProfile = new D6_Value_Assistance_Manager.ObjectService.PropertyProfile();
                String[] attributes = new String[1];
                attributes[0] = "test_value_assistance";
                propertyProfile.IncludeProperties = attributes;

                D6_Value_Assistance_Manager.ObjectService.OperationOptions opsOptions = new D6_Value_Assistance_Manager.ObjectService.OperationOptions();
                opsOptions.Profiles = new D6_Value_Assistance_Manager.ObjectService.Profile[1];
                opsOptions.Profiles[0] = propertyProfile;

                using (OperationContextScope scope = new OperationContextScope(m_objectService.InnerChannel))
                {
                    OperationContext.Current.OutgoingMessageHeaders.Add(m_scx);
                    //m_schemaService.getDynamicAssistValues("DMS", "DEFAULT", "dlau_custom_type", "value_assistance", property_set, null);

                    dataPackage = m_objectService.get(objectIdSet, opsOptions);
                    


                }

            }
            catch (Exception ex)
            {
                ErrorWnd errorWindow = new ErrorWnd(ex);
                errorWindow.Show();
            }
        }

        public String[] displayValueAssistance(String customType, String customAttribute)
        {

            if (String.IsNullOrEmpty(customType))
            {
                return null;
            }
            if (String.IsNullOrEmpty(customAttribute))
            {
                return null;
            }

            List<String> valueAssistance = new List<String>();

            String dqlStr = null;

            dqlStr = "SELECT valid_values FROM dm_value_list WHERE parent_id = (SELECT r_object_id FROM dm_aggr_domain WHERE type_name = '" + customType + "' AND ANY attr_name = '" + customAttribute + "')";

            using (OperationContextScope scope = new OperationContextScope(m_queryService.InnerChannel))
            {
                OperationContext.Current.OutgoingMessageHeaders.Add(m_scx);
                D6_Value_Assistance_Manager.QueryService.PassthroughQuery query = new D6_Value_Assistance_Manager.QueryService.PassthroughQuery();
                query.queryString = dqlStr;
                query.repositories = new String[1];
                query.repositories[0] = m_currRepositoryName;

                D6_Value_Assistance_Manager.QueryService.QueryExecution queryEx = new D6_Value_Assistance_Manager.QueryService.QueryExecution();
                queryEx.cacheStrategyType = D6_Value_Assistance_Manager.QueryService.CacheStrategyType.DEFAULT_CACHE_STRATEGY;
                queryEx.cacheStrategyTypeSpecified = true;
                queryEx.maxResultCount = 4;

                //Run the query
                D6_Value_Assistance_Manager.QueryService.QueryResult results = null;

                try
                {
                    results = m_queryService.execute(query, queryEx, null);
                }
                catch (Exception ex)
                {
                    ErrorWnd errorWindow = new ErrorWnd(ex);
                    errorWindow.Show();
                }

                if (null != results)
                {
                    foreach (D6_Value_Assistance_Manager.QueryService.DataObject valueAssistObject in results.dataPackage.DataObjects)
                    {
                        D6_Value_Assistance_Manager.QueryService.PropertySet valueAssistPropertySet = valueAssistObject.Properties;
                        D6_Value_Assistance_Manager.QueryService.StringArrayProperty valueStrArray = (D6_Value_Assistance_Manager.QueryService.StringArrayProperty) valueAssistPropertySet.Properties[0];
                        String valueStr = valueStrArray.Values[0];
                        valueAssistance.Add(valueStr);

                    }

                    return valueAssistance.ToArray();
                }

            }


            return null;

        }

        public void setCurrentRepository(String currRepositoryName)
        {
            if (String.IsNullOrEmpty(currRepositoryName))
            {
                return;
            }
            if (null == m_repositoryList || m_repositoryList.Count() == 0)
            {
                return;
            }

            m_currRepositoryName = currRepositoryName;

            IEnumerable<Repository> rCurrRepository = null;

            try
            {
                rCurrRepository = from Repository r in m_repositoryList
                                  where r.name.Equals(currRepositoryName)
                                  select r;
            }
            catch (Exception ex)
            {

            }

            if (null == rCurrRepository || rCurrRepository.Count() == 0)
            {
                return;
            }

            m_currRepository = rCurrRepository.First<Repository>();

            m_scx = new ServiceContextHeader();
            RepositoryIdentity repositoryId = new RepositoryIdentity();
            repositoryId.repositoryName = m_currRepository.name;
            repositoryId.userName = "";
            repositoryId.password = "";

            m_scx.AddRepositoryIdentity(repositoryId);


        }

        public Boolean updateValueAssistance(String customType, String customAttribute, String valueAssistanceValues)
        {
            if (String.IsNullOrEmpty(customType))
            {
                return false;
            }
            if (String.IsNullOrEmpty(customAttribute))
            {
                return false;
            }
            if (String.IsNullOrEmpty(valueAssistanceValues))
            {
                return false;
            }

            Char[] separator = new Char[1];
            separator[0] = ',';
            String[] valueAssistanceArray = valueAssistanceValues.Split(separator);

            String commonDqlPiece = "ALTER TYPE " + customType + " MODIFY (" + customAttribute + " (";
            String valueAssistancePiece = "VALUE ASSISTANCE IS LIST(";
            int numOfValueAssistanceObjects = valueAssistanceArray.Count();
            StringBuilder valueListBuilder = new StringBuilder();
            StringBuilder mappingTableBuilder = new StringBuilder();

            Boolean blankLastEntry = false;

            if (String.IsNullOrEmpty(valueAssistanceArray[valueAssistanceArray.Count() - 1]))
            {
                blankLastEntry = true;
            }

            for (int i = 0; i < numOfValueAssistanceObjects; i++)
            {
                valueListBuilder.Append("'");
                valueListBuilder.Append(valueAssistanceArray[i]);
                valueListBuilder.Append("'");

                mappingTableBuilder.Append("VALUE=");
                mappingTableBuilder.Append(valueAssistanceArray[i]);
                mappingTableBuilder.Append(" DISPLAY='");

                mappingTableBuilder.Append(valueAssistanceArray[i]);
                mappingTableBuilder.Append("'");

                if (i < numOfValueAssistanceObjects - 2)
                {
                    valueListBuilder.Append(", ");
                    mappingTableBuilder.Append(", ");
                }
                if (i == numOfValueAssistanceObjects - 2 && !blankLastEntry)
                {
                    valueListBuilder.Append(", ");
                    mappingTableBuilder.Append(", ");
                }

            }

            String endOfQuery = ") IS COMPLETE)) PUBLISH";
            String dqlStr = commonDqlPiece + valueAssistancePiece + valueListBuilder.ToString() + endOfQuery;

            using (OperationContextScope scope = new OperationContextScope(m_queryService.InnerChannel))
            {
                OperationContext.Current.OutgoingMessageHeaders.Add(m_scx);
                D6_Value_Assistance_Manager.QueryService.PassthroughQuery query = new D6_Value_Assistance_Manager.QueryService.PassthroughQuery();
                //D6_Value_Assistance_Manager.QueryService.StructuredQuery query = new D6_Value_Assistance_Manager.QueryService.StructuredQuery();
                query.queryString = dqlStr;
                //query.isDatabaseSearch = false;
                query.repositories = new String[1];
                query.repositories[0] = m_currRepositoryName;

                D6_Value_Assistance_Manager.QueryService.QueryExecution queryEx = new D6_Value_Assistance_Manager.QueryService.QueryExecution();
                queryEx.cacheStrategyType = D6_Value_Assistance_Manager.QueryService.CacheStrategyType.DEFAULT_CACHE_STRATEGY;
                queryEx.cacheStrategyTypeSpecified = true;
                queryEx.maxResultCount = 4;

                //Run the query
                D6_Value_Assistance_Manager.QueryService.QueryResult results = null;



                try
                {
                    results = m_queryService.execute(query, queryEx, null);
                    return true;
                }
                catch (Exception ex)
                {
                    ErrorWnd errorWindow = new ErrorWnd(ex);
                    errorWindow.Show();
                }


            }

            return false;

        }

        #endregion Methods

    }
}
